Skip to content

Mariano/stuff#44

Merged
Marfuen merged 4 commits into
mainfrom
mariano/stuff
Feb 12, 2025
Merged

Mariano/stuff#44
Marfuen merged 4 commits into
mainfrom
mariano/stuff

Conversation

@Marfuen
Copy link
Copy Markdown
Contributor

@Marfuen Marfuen commented Feb 12, 2025

Summary by CodeRabbit

  • New Features

    • Introduced several new policy documents, including Access Onboarding and Termination, Application Security, Availability, System Change, and Data Classification policies.
    • Expanded the compliance framework with added controls addressing security communications, system availability, data integrity, and privacy.
    • Enhanced policy data retrieval for smoother viewing.
  • Refactor

    • Streamlined policy dashboards and pages for simplified navigation.
    • Improved the policy editor experience with refined content initialization and accurate character count updates.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 12, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 12, 2025 6:28pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
web ⬜️ Skipped (Inspect) Feb 12, 2025 6:28pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 12, 2025

Walkthrough

This pull request makes extensive updates to policy-related functionality. It updates method signatures and database queries in action files to use organization-specific policies and adds a new JSON‑typed “content” field throughout. Several UI components have been revised with updated imports and logic, including the introduction of a custom SWR hook for fetching policies. New server‑side functions, JSON policy documents, and seeding data files have been added, while outdated logic related to session checks and internationalization has been removed. Database migrations and Prisma schema updates support these structural changes.

Changes

File(s) Change Summary
apps/app/src/actions/.../select-frameworks-action.ts
apps/app/src/actions/.../update-policy-action.ts
Updated policy functions: imported InputJsonValue, added a typed content array, and replaced db.artifact with db.organizationPolicy for consistency.
apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/Components/PoliciesOverview.tsx
apps/app/src/app/[locale]/(app)/(dashboard)/policies/Actions/get-policy.ts
apps/app/src/app/[locale]/(app)/(dashboard)/policies/[id]/{layout,page}.tsx
apps/app/src/app/[locale]/(app)/(dashboard)/policies/hooks/usePolicy.ts
Revised dashboard and policy pages: introduced a new server‑side getPolicy function and a custom SWR hook (usePolicy) for policy fetching, simplified layout logic by removing session/i18n checks, and updated import paths.
apps/app/src/components/editor/advanced-editor.tsx
apps/app/src/components/policies/charts/policies-by-framework.tsx
apps/app/src/components/policies/policy-overview.tsx
Adjusted component properties and state initialization: updated the PolicyEditor signature and integrated the new usePolicy hook in PolicyOverview, including revised import paths.
apps/app/src/jobs/seed/policies/access.json
apps/app/src/jobs/seed/policies/application.json
Updated JSON seed files: restructured metadata and control fields for access and application policies.
packages/data/categories/soc2.json
packages/data/controls/soc2.json
Enhanced data files: added new SOC2 criteria and controls covering availability, confidentiality, processing integrity, and privacy.
packages/data/policies/access.json
packages/data/policies/application.json
packages/data/policies/availability.json
packages/data/policies/change.json
packages/data/policies/classification.json
Added new policy documents: defined Access Onboarding, Application Security, Availability, System Change, and Data Classification policies in structured JSON.
packages/data/policies/password_policy.json Revised password policy structure: grouped metadata under a new object and introduced an empty content array while changing the format of the usedBy field.
packages/db/prisma/migrations/20250211223842_policy_column_change/migration.sql
packages/db/prisma/migrations/20250211224712_policy_column_change/migration.sql
packages/db/prisma/migrations/20250212175319_add_content_to_organization_policy/migration.sql
packages/db/prisma/schema.prisma
Performed database migrations and schema changes: dropped the template column, added content fields, modified the subdomain default and constraints, and created a unique index on subdomain.
packages/db/prisma/seed.ts
packages/db/prisma/seedTypes.ts
Updated seeding logic and types: refined policy creation using new metadata structure and introduced a new Policy interface for improved type safety.

Sequence Diagram(s)

sequenceDiagram
    participant P as PolicyOverview Component
    participant H as usePolicy Hook
    participant F as fetchPolicy Function
    participant API as getPolicy API
    participant DB as Database

    P->>H: Render with policyId
    H->>F: Call fetchPolicy(policyId)
    F->>API: Request policy data
    API->>DB: Query organizationPolicy.findFirst(...)
    DB-->>API: Return policy data
    API-->>F: Send response
    F-->>H: Return data/error
    H-->>P: Provide policy data for rendering
Loading

Poem

I'm a rabbit hopping through lines of code,
Leaping with updates on every node.
Policies refined and databases kissed,
New hooks and schemas that cannot be missed.
I nibble on changes with a joyful heart,
Hopping ahead, a fresh start in every part!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🔭 Outside diff range comments (3)
apps/app/src/actions/framework/select-frameworks-action.ts (1)

33-38: ⚠️ Potential issue

Fix Promise.all usage.

The Promise.all is being used incorrectly. frameworkIds.map() returns an array, but it's not being spread into Promise.all. This could lead to unexpected behavior.

Apply this diff to fix the Promise.all usage:

-      await Promise.all([
-        frameworkIds.map((frameworkId) =>
-          createOrganizationFramework(user as User, frameworkId)
-        ),
-        createOrganizationPolicy(user as User, frameworkIds),
-      ]);
+      await Promise.all([
+        ...frameworkIds.map((frameworkId) =>
+          createOrganizationFramework(user as User, frameworkId)
+        ),
+        createOrganizationPolicy(user as User, frameworkIds),
+      ]);
apps/app/src/components/editor/advanced-editor.tsx (1)

89-91: ⚠️ Potential issue

Fix useEffect dependency.

The useEffect hook is missing setCharsCount in its dependency array. This could lead to stale closure issues.

Apply this diff to fix the dependency array:

  useEffect(() => {
    setCharsCount(initialContent.length);
-  }, [initialContent]);
+  }, [initialContent, setCharsCount]);
apps/app/src/jobs/seed/policies/access.json (1)

394-441: 🛠️ Refactor suggestion

⚠️ Potential issue

Security concern: Delayed access termination.

The current offboarding procedure allows up to 5 business days for access termination after HR notification, which is sent weekly. This means a terminated employee could retain access for up to 7-12 days after termination, posing a significant security risk.

Consider:

  1. Implementing immediate access termination upon employee termination.
  2. Using automated systems to revoke access as soon as termination is processed.
  3. Requiring same-day notification from HR to IT for terminations.

Would you like me to propose a revised offboarding procedure that addresses these security concerns?

🧹 Nitpick comments (10)
packages/db/prisma/seed.ts (1)

303-322: Upsert policy-control mapping.

Mapping policies to control codes is explicit and direct. If multiple frameworks share the same control code, ensure you're comfortable with potential collisions. Namespacing the control code by framework ID is an option if collisions are possible.

apps/app/src/components/policies/policy-overview.tsx (1)

5-10: SWR usage to fetch policy.

The usePolicy hook simplifies data retrieval. Consider adding a dedicated loading or error state to improve the user experience while fetching.

packages/db/prisma/seedTypes.ts (1)

29-41: LGTM! Consider adding JSDoc comments.

The Policy interface is well-structured with clear separation between metadata and content. The use of JsonArray for content provides flexibility in storing policy data.

Add JSDoc comments to document the purpose of the interface and its properties:

+/**
+ * Represents a policy with metadata and content.
+ */
 export interface Policy {
+  /**
+   * Metadata containing policy information and usage details.
+   */
   metadata: {
     id: string;
     slug: string;
     name: string;
     description: string;
     type: string;
     usedBy: {
       [key: string]: string[];
     };
   };
+  /**
+   * Policy content stored as a JSON array.
+   */
   content: JsonArray;
 }
apps/app/src/app/[locale]/(app)/(dashboard)/policies/hooks/usePolicy.ts (2)

13-23: Enhance error handling with specific error messages.

While the error handling is functional, it could be more informative by providing specific error messages based on different failure scenarios.

 async function fetchPolicy(
   policyId: string
 ): Promise<OrganizationPolicyWithPolicy> {
   const response = await getPolicy({ policyId });

-  if (!response?.data?.success || !response.data.data) {
-    throw new Error(response?.data?.error || "Failed to fetch policy data");
+  if (!response?.data) {
+    throw new Error("No response received from the server");
+  }
+  if (!response.data.success) {
+    throw new Error(response.data.error || "Server returned an unsuccessful response");
+  }
+  if (!response.data.data) {
+    throw new Error("No policy data found");
   }

   return response.data.data;
 }

25-42: Document revalidation strategy and add JSDoc comments.

The hook is well-implemented but could benefit from documentation explaining the revalidation strategy.

+/**
+ * Custom hook for fetching and caching policy data.
+ * Note: Automatic revalidation is disabled to prevent unnecessary API calls.
+ * Manual revalidation can be triggered using the returned `mutate` function.
+ * @param policyId - The ID of the policy to fetch
+ * @returns Object containing policy data, loading state, error state, and mutate function
+ */
 export function usePolicy({ policyId }: { policyId: string }) {
   const { data, error, isLoading, mutate } =
     useSWR<OrganizationPolicyWithPolicy>(
       [POLICY_KEY, policyId],
       () => fetchPolicy(policyId),
       {
         revalidateOnFocus: false,
         revalidateOnReconnect: false,
+        // Consider adding dedupingInterval to prevent redundant requests
+        dedupingInterval: 5000,
       }
     );

   return {
     data,
     isLoading,
     error,
     mutate,
   };
 }
apps/app/src/app/[locale]/(app)/(dashboard)/policies/Actions/get-policy.ts (1)

52-57: Include error details in the response.

The error message could be more informative by including the actual error details.

 } catch (error) {
   return {
     success: false,
-    error: "Failed to fetch policy statistics",
+    error: `Failed to fetch policy statistics: ${error instanceof Error ? error.message : 'Unknown error'}`,
   };
 }
apps/app/src/components/editor/advanced-editor.tsx (1)

83-83: Consider adjusting debounce timeout.

The 1000ms debounce timeout might feel sluggish for users. Consider reducing it to 500ms for a better balance between performance and responsiveness.

-    1000
+    500
packages/data/policies/password_policy.json (1)

11-11: Populate the content array with policy requirements.

The content array is currently empty. Consider adding the password policy requirements such as minimum length, complexity rules, etc.

Would you like me to help generate a structured content array with common password policy requirements?

packages/data/policies/classification.json (1)

12-768: Consider implementing version control for policy content.

The policy content is well-structured but lacks version tracking within the content itself. While the metadata includes SOC2 mappings, adding version information within the content would help track changes to specific sections.

Add a version field to each major section:

 {
   "type": "heading",
   "attrs": { "level": 2 },
+  "version": "1.0",
   "content": [
     {
       "type": "text",
       "text": "Policy Information"
     }
   ]
 }
packages/data/policies/application.json (1)

372-409: Add definitions for medium and low risk levels.

The policy only defines high risk vulnerabilities. For completeness and clarity, consider adding definitions for medium and low risk levels to help teams properly prioritize and handle all types of vulnerabilities.

Add these sections after the high risk definition:

      ]
    },
+    {
+      "type": "heading",
+      "attrs": { "level": 4 },
+      "content": [{ "type": "text", "text": "Medium Risk" }]
+    },
+    {
+      "type": "bulletList",
+      "content": [
+        {
+          "type": "listItem",
+          "content": [
+            {
+              "type": "paragraph",
+              "content": [
+                {
+                  "type": "text",
+                  "text": "Issues must be fixed within 30 days"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "heading",
+      "attrs": { "level": 4 },
+      "content": [{ "type": "text", "text": "Low Risk" }]
+    },
+    {
+      "type": "bulletList",
+      "content": [
+        {
+          "type": "listItem",
+          "content": [
+            {
+              "type": "paragraph",
+              "content": [
+                {
+                  "type": "text",
+                  "text": "Issues should be fixed during the next planned release"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b51d444 and 04a7ed7.

📒 Files selected for processing (26)
  • apps/app/src/actions/framework/select-frameworks-action.ts (2 hunks)
  • apps/app/src/actions/policies/update-policy-action.ts (3 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/Components/PoliciesOverview.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/Actions/get-policy.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[id]/layout.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[id]/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/hooks/usePolicy.ts (1 hunks)
  • apps/app/src/components/editor/advanced-editor.tsx (2 hunks)
  • apps/app/src/components/policies/charts/policies-by-framework.tsx (1 hunks)
  • apps/app/src/components/policies/policy-overview.tsx (1 hunks)
  • apps/app/src/jobs/seed/policies/access.json (1 hunks)
  • apps/app/src/jobs/seed/policies/application.json (1 hunks)
  • packages/data/categories/soc2.json (1 hunks)
  • packages/data/controls/soc2.json (2 hunks)
  • packages/data/policies/access.json (1 hunks)
  • packages/data/policies/application.json (1 hunks)
  • packages/data/policies/availability.json (1 hunks)
  • packages/data/policies/change.json (1 hunks)
  • packages/data/policies/classification.json (1 hunks)
  • packages/data/policies/password_policy.json (1 hunks)
  • packages/db/prisma/migrations/20250211223842_policy_column_change_type/migration.sql (1 hunks)
  • packages/db/prisma/migrations/20250211224712_policy_column_change/migration.sql (1 hunks)
  • packages/db/prisma/migrations/20250212175319_add_content_to_organization_policy/migration.sql (1 hunks)
  • packages/db/prisma/schema.prisma (2 hunks)
  • packages/db/prisma/seed.ts (5 hunks)
  • packages/db/prisma/seedTypes.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[id]/layout.tsx
🔇 Additional comments (28)
apps/app/src/app/[locale]/(app)/(dashboard)/policies/[id]/page.tsx (1)

12-12: Consider adding authentication or a guard.

With the removal of session checks, it appears that the user can access the policy page without an active session. Ensure that you handle authentication and authorization at a higher level or confirm that this route is still protected.

packages/db/prisma/seed.ts (9)

1-2: Imports look good.

No issues found with the new import statements for PrismaClient and RequirementType, Prisma types.


6-12: Ensure that the imported types are correct.

The new imports for FrameworkCategory, Framework, Control, Policy, and JsonValue appear correct. Confirm that each of these types properly matches the shape of your data, especially JsonValue in the new content fields.


19-22: Cautious approach to data cleanup.

You're deleting multiple entities, including policyControl, policyFramework, controlRequirement, organizationPolicy, and others. This ensures a clean slate before seeding. Make sure there's no data dependency that might cause foreign key or ordering issues.

Also applies to: 24-24, 26-27


66-66: Validate the Policy shape.

Typecasting policyData as Policy is helpful for type safety, but ensure that the JSON file structure actually matches the Policy interface at runtime.


69-74: Upsert logic for policy content.

Storing metadata.usedBy and content as Prisma.InputJsonValue[] ensures flexible data entry. Confirm that these arrays do not exceed typical size constraints in your database, and handle potential edge cases (e.g., empty arrays).

Also applies to: 77-82


208-208: Using control code as both id and code.

This approach is straightforward, but be aware of collisions if multiple frameworks share identical control codes. Ensure that uniqueness constraints are sufficient for your domain.


223-235: Policy existence check.

Good practice to verify that a policy referenced in a requirement actually exists. The console warning helps identify missing references. Consider a more robust handling approach (e.g., an error) if skipping is insufficient for your domain logic.


276-288: Framework existence check.

This ensures you don't map policies to a non-existent framework. Logging a warning for missing or invalid mappings is helpful.


289-300: Upsert policy-framework relationship.

Maintaining a composite key with ${frameworkId}_${policy.id} prevents duplicates across frameworks. This logic cleanly avoids collisions.

apps/app/src/components/policies/policy-overview.tsx (1)

18-18: Passing policyId to editor.

The updated approach ensures the editor operates on the correct policy context. All good here.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/Components/PoliciesOverview.tsx (1)

35-36: Verify the commented-out components.

The component has commented-out sections that might affect functionality:

  • <PolicyOverview data={data} />
  • <PoliciesByAssignee organizationId={organizationId} />

Please verify if these components should be removed or re-enabled.

Also applies to: 40-41

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check if the commented-out components are used elsewhere or have replacements

# Search for PolicyOverview component
echo "Searching for PolicyOverview component..."
rg -l "PolicyOverview"

# Search for PoliciesByAssignee component
echo "Searching for PoliciesByAssignee component..."
rg -l "PoliciesByAssignee"

Length of output: 680


Action: Remove the unnecessary commented code in the overview component.

The search confirms that while the base components (PolicyOverview and PoliciesByAssignee) exist in other parts of the repository (e.g., within the charts folder and another page), they are not active in this overview file. Since <PoliciesByFramework /> is the active replacement here, the commented-out lines can safely be removed to clean up the code.

apps/app/src/components/policies/charts/policies-by-framework.tsx (1)

3-3: LGTM!

The import path update aligns with the directory restructuring changes.

apps/app/src/actions/policies/update-policy-action.ts (2)

20-20: LGTM!

The type annotation for the content parameter enhances type safety.


77-79: LGTM!

The database model change from artifact to organizationPolicy improves data organization and aligns with the broader refactoring effort. The query includes proper organization-level access control.

Also applies to: 93-96

apps/app/src/actions/framework/select-frameworks-action.ts (2)

7-7: LGTM!

The import of InputJsonValue type from Prisma enhances type safety for JSON handling.


140-140: LGTM!

The type casting of policy content to InputJsonValue[] ensures type safety and aligns with the database schema.

apps/app/src/components/editor/advanced-editor.tsx (1)

35-45: LGTM!

The changes improve type safety and ensure proper document structure:

  • Props type definition is more explicit.
  • Initial content structure follows the required "doc" format.
packages/db/prisma/migrations/20250211224712_policy_column_change/migration.sql (1)

1-2: Verify handling of existing organizations after default value removal.

Dropping the default value for the subdomain column requires explicit values for new organizations. Ensure that:

  1. Existing organizations have valid subdomain values
  2. All code paths setting up new organizations explicitly set the subdomain
❌ Verification inconclusive

🏁 Script executed:

#!/bin/bash
# Check for organizations with null/empty subdomains
echo "Checking for organizations with null/empty subdomains..."
rg -A 5 "new Organization\(" # Find organization creation code
rg -A 5 "createMany.*Organization" # Find bulk creation code

Length of output: 190


Verify explicit subdomain handling in organization creation paths

Our initial search did not reveal any explicit code fragments (i.e., using new Organization( or bulk creation methods) that assign a subdomain value. This absence of evidence means we can't confirm whether new organization creation always provides a non-null subdomain. Additionally, it’s unclear if existing organizations have been updated to guarantee valid subdomain values following the removal of the default.

Please ensure that:

  • A data migration or seed update covers existing records to assign valid subdomain values.
  • All code paths for creating new organizations have been reviewed to explicitly set a subdomain.
packages/data/policies/password_policy.json (1)

2-10: LGTM! Well-structured metadata organization.

Good separation of metadata from content, making the policy structure more maintainable.

packages/data/policies/classification.json (1)

1-11: LGTM! Well-structured metadata section.

The metadata section is well-organized with clear identification and SOC2 mapping references.

packages/data/policies/availability.json (1)

1-709: LGTM! Well-defined availability policy structure.

The availability policy follows the same structure as the classification policy, maintaining consistency across policy documents.

packages/db/prisma/schema.prisma (2)

847-847: LGTM! Updated Policy model with JSON array support.

The change from template to content field using Json[] type aligns with the new structured policy format.


948-948: Verify content field indexing requirements.

Consider whether the content field needs indexing for search functionality.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Check if any existing queries use content field filtering
rg -A 5 "content.*where" apps/

Length of output: 32


I'm going to run additional searches to gather more details on whether the content field is used in filtering queries and if there's any existing indexing defined in the Prisma schema. This will help us determine if an index should be added to support search functionality.

Once these commands run and we review their output, we can definitively decide whether the content field needs indexing. If no queries rely on filtering this field, it is likely that no index is currently required. However, if search functionality is planned or such queries are added later, consider evaluating a suitable index (e.g. a GIN index if on PostgreSQL) for JSON fields.

Action Required:
• Manually review the output of the above searches to verify how the content field is used across the repository.
• Based on that, decide if adding an index for search optimization is necessary now or in the future.


🏁 Script executed:

#!/bin/bash
set -e

echo "1. Checking for index definitions referencing the 'content' field in the Prisma schema:"
rg -n "@@index" packages/db/prisma/schema.prisma

echo
echo "2. Confirming the definition of the 'content' field in the Prisma schema:"
rg -n "content\s+Json\[\]" packages/db/prisma/schema.prisma

echo
echo "3. Searching the entire repository for queries filtering on the 'content' field (looking for patterns like where: { ... content ... }):"
rg -n "where\s*:\s*{[^}]*content" .

Length of output: 2886


I'll run an updated search using Perl-compatible regex so we can verify if any queries filter on the content field, avoiding the previous regex error. This should help us determine if indexing is used in practice for search functionality.

Please review the output when it's available.


🏁 Script executed:

#!/bin/bash
set -e

echo "Searching the entire repository for queries filtering on the 'content' field using Perl-compatible regex:"
rg -n -P "where\s*:\s*\{[^}]*content" .

Length of output: 277


Content Field Indexing Verification Outcome

  • The Prisma schema shows two instances of the content field defined as Json[] (lines 847 and 948) with no index definitions for this field.
  • Search results confirm that there are no queries filtering on the content field.

Based on the current codebase, no indexing exists or appears necessary for the content field to support search functionality. Consider revisiting this decision if future requirements introduce filtering or search queries targeting this field.

packages/data/controls/soc2.json (1)

707-731: LGTM! Well-structured security event communication control.

The CC7.5 control is well-defined with clear requirements for policy, procedure, and evidence.

packages/data/policies/access.json (1)

1-11: LGTM! Well-structured metadata with appropriate SOC2 controls.

The metadata section is well-organized and correctly references the relevant SOC2 controls (CC6.1, CC6.2, CC6.4, CC6.8) for access management.

apps/app/src/jobs/seed/policies/application.json (1)

4-4: Verify the change in SOC2 controls alignment.

The controls have been updated from CC6.2 (access control) to CC7.1, CC7.2, CC7.4 (system operations, monitoring, and change management). Please confirm this shift aligns with the intended compliance requirements.

Run this script to check for any dependencies on the old control:

❌ Verification inconclusive

🏁 Script executed:

#!/bin/bash
# Search for references to the old control CC6.2
rg -l "CC6\.2"

# Search for any validation logic that might need updating
ast-grep --pattern 'controls.includes("CC6.2")'

Length of output: 244


SOC2 Controls Update Verification

The update in apps/app/src/jobs/seed/policies/application.json to use CC7.1, CC7.2, CC7.4 instead of CC6.2 appears intentional for the application policy’s compliance alignment. However, the shell script revealed that several other files still reference CC6.2:

  • apps/app/src/utils/soc2-data.ts
  • apps/app/src/jobs/seed/policies/access.json
  • apps/app/src/lib/soc2-controls.ts
  • packages/data/controls/soc2.json
  • packages/data/policies/access.json

Please verify whether these remaining references are intended for different policy types (e.g., an access policy) or if a broader update is required to align all SOC2-related policies with the new controls.

packages/data/policies/application.json (1)

1-11: LGTM! Well-structured metadata with appropriate SOC2 controls.

The metadata section is well-organized and correctly references the relevant SOC2 controls (CC7.1, CC7.2, CC7.4) for application security.

Comment on lines +11 to +15
export type PolicyStatsResponse = {
success: boolean;
data?: OrganizationPolicy[];
error?: string;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the response type definition.

The PolicyStatsResponse type's data property should be a single OrganizationPolicy or undefined, not an array, as the findFirst query returns a single record.

 export type PolicyStatsResponse = {
   success: boolean;
-  data?: OrganizationPolicy[];
+  data?: OrganizationPolicy;
   error?: string;
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type PolicyStatsResponse = {
success: boolean;
data?: OrganizationPolicy[];
error?: string;
};
export type PolicyStatsResponse = {
success: boolean;
data?: OrganizationPolicy;
error?: string;
};

Comment on lines +37 to +46
try {
const policy = await db.organizationPolicy.findFirst({
where: {
organizationId: user.organizationId!,
id: policyId,
},
include: {
policy: true,
},
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add null check and improve error handling.

The database query could be improved with better error handling and null checks.

 try {
   const policy = await db.organizationPolicy.findFirst({
     where: {
-      organizationId: user.organizationId!,
+      organizationId: user.organizationId,
       id: policyId,
     },
     include: {
       policy: true,
     },
   });

+  if (!policy) {
+    return {
+      success: false,
+      error: "Policy not found",
+    };
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
const policy = await db.organizationPolicy.findFirst({
where: {
organizationId: user.organizationId!,
id: policyId,
},
include: {
policy: true,
},
});
try {
const policy = await db.organizationPolicy.findFirst({
where: {
organizationId: user.organizationId,
id: policyId,
},
include: {
policy: true,
},
});
if (!policy) {
return {
success: false,
error: "Policy not found",
};
}

Comment on lines +1 to +2
-- AlterTable
ALTER TABLE "OrganizationPolicy" ADD COLUMN "content" JSONB[];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🛠️ Refactor suggestion

🧩 Analysis chain

Consider data migration strategy for existing organization policies.

Adding the content column without a default value means existing records will have null content. Consider:

  1. Adding a data migration script to populate content for existing records
  2. Documenting the expected content structure in JSONB array

🏁 Script executed:

#!/bin/bash
# Check for existing organization policies
echo "Checking for existing organization policies..."
rg -A 5 "organizationPolicy.*create"
rg -A 5 "organizationPolicy.*update"

Length of output: 1297


Attention: Add Data Migration Script to Populate Existing Organization Policies

The migration adds the new JSONB[] column "content" without a default value, which means that existing records will have a null value. The code paths for creating and updating organization policies (as shown in the search results) rely on this column, but do not handle a potential null state. Please consider adding a migration script to update existing records (for example, setting "content" to an empty array) and document the expected JSONB structure.

Comment on lines +1 to +7
/*
Warnings:

- You are about to drop the column `template` on the `Policy` table. All the data in the column will be lost.
- A unique constraint covering the columns `[subdomain]` on the table `Organization` will be added. If there are existing duplicate values, this will fail.

*/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Review warnings and prepare mitigation steps.

Critical migration warnings:

  1. Data loss from Policy.template column
  2. Potential failure due to duplicate subdomains

Before applying this migration:

  1. Backup template data
  2. Check for and resolve duplicate subdomains
  3. Consider breaking this into smaller migrations
#!/bin/bash
# Check for duplicate subdomains
echo "Checking for duplicate subdomains in organization creation code..."
rg -A 5 "subdomain.*Organization"

Comment on lines +8 to +14
-- AlterTable
ALTER TABLE "Organization" ADD COLUMN "subdomain" TEXT NOT NULL DEFAULT 'example.com';

-- AlterTable
ALTER TABLE "Policy" DROP COLUMN "template",
ADD COLUMN "content" JSONB[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider data migration for template to content conversion.

The template column is being replaced with a JSONB array content column. Ensure there's a strategy to:

  1. Convert existing template data to the new content format
  2. Update all code that previously used the template field

🏁 Script executed:

#!/bin/bash
# Find usages of template field
echo "Checking for template field usage..."
rg -A 5 "template.*Policy"

Length of output: 1000


Data migration step missing for converting template data

The migration file only drops the "template" column and adds the "content" column without handling the conversion of existing data. Additionally, there are no indications elsewhere in the codebase that the necessary data transformation or updates to references of "template" have been applied.

  • Location: packages/db/prisma/migrations/20250211223842_policy_column_change_type/migration.sql (Lines 8–14)
  • Action: Add a data migration step to convert existing "template" data to the new JSONB array format in "content" and update all parts of the code that previously interacted with the "template" field.

Comment on lines +47 to 66
"A1": {
"name": "A1: Availability",
"code": "A1",
"description": "This criterion ensures that systems are available for operation and use as committed or agreed."
},
"C1": {
"name": "C1: Data Integrity",
"code": "C1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
},
"PI1": {
"name": "PI1: Processing Integrity",
"code": "PI1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
},
"P1": {
"name": "P1: Privacy",
"code": "P1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update descriptions for C1, PI1, and P1 categories.

The descriptions for C1 (Data Integrity), PI1 (Processing Integrity), and P1 (Privacy) are identical. Each category should have a unique description that reflects its specific focus:

  • C1 should focus on data integrity controls
  • PI1 should emphasize system processing accuracy
  • P1 should detail privacy protection measures

Suggested updates:

  "C1": {
    "name": "C1: Data Integrity",
    "code": "C1",
-   "description": "This criterion ensures that data is accurate, complete, and consistent."
+   "description": "This criterion ensures that stored data maintains its integrity through controls preventing unauthorized modification or corruption."
  },
  "PI1": {
    "name": "PI1: Processing Integrity",
    "code": "PI1",
-   "description": "This criterion ensures that data is accurate, complete, and consistent."
+   "description": "This criterion ensures that system processing is complete, valid, accurate, timely, and authorized."
  },
  "P1": {
    "name": "P1: Privacy",
    "code": "P1",
-   "description": "This criterion ensures that data is accurate, complete, and consistent."
+   "description": "This criterion ensures that personal information is collected, used, retained, disclosed, and disposed of in accordance with privacy commitments and requirements."
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"A1": {
"name": "A1: Availability",
"code": "A1",
"description": "This criterion ensures that systems are available for operation and use as committed or agreed."
},
"C1": {
"name": "C1: Data Integrity",
"code": "C1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
},
"PI1": {
"name": "PI1: Processing Integrity",
"code": "PI1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
},
"P1": {
"name": "P1: Privacy",
"code": "P1",
"description": "This criterion ensures that data is accurate, complete, and consistent."
}
"A1": {
"name": "A1: Availability",
"code": "A1",
"description": "This criterion ensures that systems are available for operation and use as committed or agreed."
},
"C1": {
"name": "C1: Data Integrity",
"code": "C1",
"description": "This criterion ensures that stored data maintains its integrity through controls preventing unauthorized modification or corruption."
},
"PI1": {
"name": "PI1: Processing Integrity",
"code": "PI1",
"description": "This criterion ensures that system processing is complete, valid, accurate, timely, and authorized."
},
"P1": {
"name": "P1: Privacy",
"code": "P1",
"description": "This criterion ensures that personal information is collected, used, retained, disclosed, and disposed of in accordance with privacy commitments and requirements."
}

Comment on lines +8 to +12
"usedBy": {
"soc2": {
"CC6": ["CC6.1", "CC6.2", "CC6.3"]
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

⚠️ Potential issue

🧩 Analysis chain

Resolve inconsistencies in SOC2 control mappings.

The SOC2 control mappings in this file differ from its duplicate in packages/data/policies/access.json:

  • This file: CC6.1, CC6.2, CC6.3 under CC6
  • Duplicate: CC6.1, CC6.2, CC6.4, CC6.8

Please clarify which file is the source of truth and ensure consistent control mappings across both files.

Run the following script to identify all policy files and their SOC2 control mappings:


🏁 Script executed:

#!/bin/bash
# Description: Find all policy JSON files and extract their SOC2 control mappings.

# Find all policy JSON files
fd -e json -t f . apps/app/src/jobs/seed/policies packages/data/policies --exec sh -c '
  echo "=== $1 ==="
  jq -r ".metadata.usedBy.soc2 | if type == \"object\" then to_entries[] | \"\(.key): \(.value | join(\", \"))\" else join(\", \") end" "$1"
  echo
' _

Length of output: 1410


SOC2 Control Mapping Mismatch – Align Seed Policy with Authoritative Mapping

The seed policy in apps/app/src/jobs/seed/policies/access.json shows the SOC2 mapping for CC6 as “CC6.1, CC6.2, CC6.3”, while the duplicate in packages/data/policies/access.json maps CC6 as “CC6.1, CC6.2, CC6.4, CC6.8”. This discrepancy confirms the review comment’s concern. Given that the mapping in packages/data/policies/access.json appears in the central data package and is used by other policy files (e.g., see consistent detailed control sets in other packages/data files), it should be treated as the source of truth. Accordingly, update the seed file to match the mappings in packages/data/policies/access.json for consistency.

  • File Differences:

    • Seed File (apps/app/src/jobs/seed/policies/access.json): CC6 → CC6.1, CC6.2, CC6.3
    • Data Package (packages/data/policies/access.json): CC6 → CC6.1, CC6.2, CC6.4, CC6.8
  • Action:

    • Confirm that packages/data/policies/access.json is indeed the authoritative source.
    • Update the SOC2 control mappings in apps/app/src/jobs/seed/policies/access.json to align with the authoritative mappings.

Comment on lines +313 to +498
{
"type": "orderedList",
"attrs": {
"tight": true,
"start": 1
},
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Planning"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "plan the change, including the implementation design, scheduling, and implementation of a communications plan, testing plan, and roll-back plan."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Evaluation"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "evaluate the change, including priority level of the service and risk that the proposed change introduces to the system; determine the change type and the specific step-by-step process to implement the change."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Review"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "review the change plan amongst the CIO, ISM, Engineering Lead, and, if applicable, Business Unit Manager."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Approval"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "the CIO must approve the change plan."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Communication"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "communicate the change to all users of the system."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Implementation"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "test and implement the change."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Documentation"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "record the change and any post-implementation issues."
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": " Post-change review"
},
{
"type": "text",
"text": ": "
},
{
"type": "text",
"text": "conduct a post-implementation review to determine how the change is impacting the organization, either positively or negatively. Discuss and document any lessons learned."
}
]
}
]
}
]
}
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance change management procedures.

The current change management procedure is missing several critical components:

  1. Emergency change procedures for critical security patches or system outages
  2. Specific risk assessment criteria for evaluating changes
  3. Detailed testing requirements (e.g., unit tests, integration tests, security tests)
  4. Change classification (e.g., minor, major, emergency)
  5. Rollback success criteria and verification steps

Would you like me to propose additional sections that cover these missing components?

Comment on lines +832 to 1035
"A1.1": {
"code": "A1.1",
"name": "Availability Commitments",
"description": "The entity maintains commitments to ensure systems are available for operation.",
"domain": "Availability",
"categoryId": "A1",
"requirements": []
},
"A1.2": {
"code": "A1.2",
"name": "Capacity Planning",
"description": "The entity monitors and manages system capacity to meet demands.",
"domain": "Availability",
"categoryId": "A1",
"requirements": []
},
"A1.3": {
"code": "A1.3",
"name": "Incident Recovery",
"description": "The entity has controls to restore system availability after incidents.",
"domain": "Availability",
"categoryId": "A1",
"requirements": []
},
"C1.1": {
"code": "C1.1",
"name": "Confidential Information Classification",
"description": "The entity classifies information to identify and protect confidential information.",
"domain": "Confidentiality",
"categoryId": "C1",
"requirements": [
{
"id": "C1.1-policy",
"type": "policy",
"description": "Information classification policy",
"policyId": "password_policy"
},
{
"id": "C1.1-procedure",
"type": "procedure",
"description": "Information classification procedures"
}
]
},
"C1.2": {
"code": "C1.2",
"name": "Access Restrictions for Confidential Data",
"description": "The entity restricts access to confidential information on a need-to-know basis.",
"domain": "Confidentiality",
"categoryId": "C1",
"requirements": [
{
"id": "C1.2-policy",
"type": "policy",
"description": "Confidential data access policy",
"policyId": "password_policy"
},
{
"id": "C1.2-procedure",
"type": "procedure",
"description": "Confidential data access procedures"
}
]
},
"C1.3": {
"code": "C1.3",
"name": "Confidential Data Disposal",
"description": "The entity securely disposes of confidential information when no longer needed.",
"domain": "Confidentiality",
"categoryId": "C1",
"requirements": [
{
"id": "C1.3-policy",
"type": "policy",
"description": "Data disposal policy",
"policyId": "password_policy"
},
{
"id": "C1.3-procedure",
"type": "procedure",
"description": "Data disposal procedures"
}
]
},
"PI1.1": {
"code": "PI1.1",
"name": "Accuracy and Completeness",
"description": "The entity ensures data is processed accurately and completely.",
"domain": "Processing Integrity",
"categoryId": "PI1",
"requirements": [
{
"id": "PI1.1-policy",
"type": "policy",
"description": "Data accuracy policy",
"policyId": "password_policy"
},
{
"id": "PI1.1-procedure",
"type": "procedure",
"description": "Data accuracy procedures"
}
]
},
"PI1.2": {
"code": "PI1.2",
"name": "Input, Processing, and Output Controls",
"description": "The entity validates the completeness and accuracy of data throughout processing.",
"domain": "Processing Integrity",
"categoryId": "PI1",
"requirements": [
{
"id": "PI1.2-policy",
"type": "policy",
"description": "Data processing controls policy",
"policyId": "password_policy"
},
{
"id": "PI1.2-procedure",
"type": "procedure",
"description": "Data processing control procedures"
}
]
},
"PI1.3": {
"code": "PI1.3",
"name": "Exception Handling",
"description": "The entity identifies and resolves processing exceptions in a timely manner.",
"domain": "Processing Integrity",
"categoryId": "PI1",
"requirements": [
{
"id": "PI1.3-policy",
"type": "policy",
"description": "Exception handling policy",
"policyId": "password_policy"
},
{
"id": "PI1.3-procedure",
"type": "procedure",
"description": "Exception handling procedures"
}
]
},
"P1.1": {
"code": "P1.1",
"name": "Privacy Notice",
"description": "The entity provides notice about the collection, use, and disclosure of personal information.",
"domain": "Privacy",
"categoryId": "P1",
"requirements": [
{
"id": "P1.1-policy",
"type": "policy",
"description": "Privacy notice policy",
"policyId": "password_policy"
},
{
"id": "P1.1-procedure",
"type": "procedure",
"description": "Privacy notice procedures"
}
]
},
"P1.2": {
"code": "P1.2",
"name": "Choice and Consent",
"description": "The entity obtains consent for personal information where required by policy or law.",
"domain": "Privacy",
"categoryId": "P1",
"requirements": [
{
"id": "P1.2-policy",
"type": "policy",
"description": "Consent policy",
"policyId": "password_policy"
},
{
"id": "P1.2-procedure",
"type": "procedure",
"description": "Consent procedures"
}
]
},
"P1.3": {
"code": "P1.3",
"name": "Data Retention and Disposal",
"description": "The entity retains personal information for only as long as needed and disposes of it securely.",
"domain": "Privacy",
"categoryId": "P1",
"requirements": [
{
"id": "P1.3-policy",
"type": "policy",
"description": "Data retention policy",
"policyId": "password_policy"
},
{
"id": "P1.3-procedure",
"type": "procedure",
"description": "Data retention procedures"
}
]
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Review and update policy references.

All new controls reference "password_policy" which may not be appropriate for their specific domains. Consider creating domain-specific policy references.

For example, update availability controls:

 {
   "id": "A1.1-policy",
   "type": "policy",
   "description": "Availability commitments policy",
-  "policyId": "password_policy"
+  "policyId": "availability_policy"
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +418 to +424
{
"type": "text",
"text": "HR sends a weekly email report to IT summarizing list of users terminated and instructs IT to disable their access."
}
]
}
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider reducing the notification delay for access termination.

The weekly email report for terminated users could potentially leave access available for up to a week before IT is notified. This delay could pose a security risk.

Consider this alternative approach:

-    "text": "HR sends a weekly email report to IT summarizing list of users terminated and instructs IT to disable their access."
+    "text": "HR immediately notifies IT when a user is terminated and instructs IT to disable their access."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"type": "text",
"text": "HR sends a weekly email report to IT summarizing list of users terminated and instructs IT to disable their access."
}
]
}
]
{
"type": "text",
"text": "HR immediately notifies IT when a user is terminated and instructs IT to disable their access."
}
]
}
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant